package org.manci

import groovy.json.JsonBuilder
import groovy.json.JsonSlurper

/**
 * AI大模型模块 - 为ManCI提供智能化CI/CD流程控制
 * 
 * 功能特性：
 * - OpenAI接口封装
 * - Gitee评论@ai指令解析
 * - 自然语言需求转换为ManCI指令
 * - 基于项目上下文的智能提示生成
 */
class AI implements Serializable {
    def script
    Logger logger
    Utils utils
    
    // 配置属性
    String apiUrl
    String apiKey
    String model
    boolean enabled
    int maxTokens
    double temperature
    int timeout
    
    // 构造函数
    AI(script) {
        this.script = script
        this.logger = new Logger(script)
        this.utils = new Utils(script)
        
        // 初始化配置
        initializeConfig()
        
        logger.info("AI模块初始化完成 - 状态: ${enabled ? '启用' : '禁用'}")
    }
    
    /**
     * 初始化配置参数
     */
    private void initializeConfig() {
        // 基础配置
        this.enabled = script.env.ENABLED_AI?.toLowerCase() == 'true'
        this.apiUrl = script.env.OPENAI_API_URL ?: 'https://api.openai.com/v1'
        this.apiKey = script.env.OPENAI_API_KEY
        
        // 高级配置
        this.model = script.env.OPENAI_MODEL ?: 'gpt-3.5-turbo'
        this.maxTokens = (script.env.OPENAI_MAX_TOKENS ?: '1000') as Integer
        this.temperature = (script.env.OPENAI_TEMPERATURE ?: '0.7') as Double
        this.timeout = (script.env.OPENAI_TIMEOUT ?: '30') as Integer
        
        // 验证必要配置
        if (enabled && !apiKey) {
            logger.warning("AI功能已启用但未配置OPENAI_API_KEY，将禁用AI功能")
            this.enabled = false
        }
    }
    
    /**
     * 处理AI评论 - 主入口方法
     * @param commentBody 评论内容
     * @param commentId 评论ID，用于回复
     * @param giteeApi Gitee API实例
     * @param table Table实例，包含项目信息
     * @param stagesInfo 阶段信息
     * @return 是否处理了AI评论
     */
    def processAIComment(String commentBody, String commentId, GiteeApi giteeApi, Table table, Map stagesInfo) {
        if (!enabled) {
            logger.debug("AI功能未启用，跳过处理")
            return false
        }
        
        if (!isAIComment(commentBody)) {
            return false
        }
        
        try {
            logger.info("检测到AI评论，开始处理...")
            
            // 提取用户需求
            String requirement = extractRequirement(commentBody)
            if (!requirement) {
                giteeApi.replyComment("❌ 无法解析AI指令，请使用格式：@ai 您的需求描述", commentId)
                return true
            }
            
            // 获取项目上下文信息
            String commentInfo = table?.commentInfo ?: ""
            Map stageInfo = buildStageInfo(stagesInfo)
            
            // 生成AI指令
            String command = generateCommand(requirement, commentInfo, stageInfo)
            
            if (command && command != "无法理解该需求，请提供更具体的描述") {
                // 验证指令格式
                if (validateCommand(command)) {
                    // 回复生成的指令
                    String replyMessage = """🤖 **AI助手**

**用户需求**: ${requirement}

**生成指令**: 
```
${command}
```

指令将自动执行..."""
                    
                    giteeApi.replyComment(replyMessage, commentId)
                    
                    // 发布指令评论以触发执行
                    giteeApi.replyComment(command, commentId)
                    
                    logger.info("AI指令生成成功: ${command}")
                } else {
                    giteeApi.replyComment("❌ 生成的指令格式不正确，请重新描述需求", commentId)
                    logger.warning("生成的指令格式验证失败: ${command}")
                }
            } else {
                giteeApi.replyComment("❌ ${command ?: '无法理解该需求，请提供更具体的描述'}", commentId)
                logger.warning("AI无法理解用户需求: ${requirement}")
            }
            
            return true
            
        } catch (Exception e) {
            logger.error("处理AI评论时发生错误: ${e.message}")
            giteeApi.replyComment("❌ 处理AI请求时发生错误，请稍后重试", commentId)
            return true
        }
    }
    
    /**
     * 检查是否为AI评论
     */
    private boolean isAIComment(String commentBody) {
        return commentBody?.trim()?.toLowerCase()?.startsWith('@ai')
    }
    
    /**
     * 提取用户需求描述
     */
    private String extractRequirement(String commentBody) {
        if (!commentBody) return null
        
        String content = commentBody.trim()
        if (content.toLowerCase().startsWith('@ai')) {
            String requirement = content.substring(3).trim()
            return requirement.isEmpty() ? null : requirement
        }
        return null
    }
    
    /**
     * 构建阶段信息
     */
    private Map buildStageInfo(Map stagesInfo) {
        if (!stagesInfo) return [:]
        
        Map result = [:]
        List<String> stages = []
        List<String> groups = []
        
        stagesInfo.each { groupName, stageList ->
            groups.add(groupName)
            stageList.each { stage ->
                stages.add(stage.name)
            }
        }
        
        result.stages = stages
        result.groups = groups
        result.stagesInfo = stagesInfo
        
        return result
    }
    
    /**
     * 生成ManCI指令
     */
    def generateCommand(String requirement, String commentInfo, Map stageInfo) {
        try {
            String prompt = buildPrompt(requirement, commentInfo, stageInfo)
            String response = callOpenAI(prompt)
            
            return response?.trim()
            
        } catch (Exception e) {
            logger.error("生成指令时发生错误: ${e.message}")
            return null
        }
    }
    
    /**
     * 构建AI提示词
     */
    def buildPrompt(String requirement, String commentInfo, Map stageInfo) {
        StringBuilder prompt = new StringBuilder()
        
        prompt.append("你是一个CI/CD专家，负责将用户的自然语言需求转换为ManCI流水线指令。\n\n")
        
        // 添加项目信息
        if (commentInfo) {
            prompt.append("项目信息和指令说明：\n")
            prompt.append(commentInfo)
            prompt.append("\n\n")
        }
        
        // 添加阶段信息
        if (stageInfo && stageInfo.stages) {
            prompt.append("当前阶段信息：\n")
            prompt.append("可用阶段: ${stageInfo.stages.join(', ')}\n")
            if (stageInfo.groups) {
                prompt.append("可用组: ${stageInfo.groups.join(', ')}\n")
            }
            prompt.append("\n")
        }
        
        // 添加支持的指令格式
        prompt.append("""支持的指令格式：
- run [stageName...]: 执行指定阶段
- run [groupName...]: 执行指定组  
- run failure: 重新执行失败阶段
- run [stage/group] [env1=value1 env2=value2...]: 带环境变量执行
- run [stage/group] withAlone=true: 独立执行

""")
        
        prompt.append("用户需求: ${requirement}\n\n")
        prompt.append("请根据项目信息分析用户需求，生成对应的ManCI指令。只返回指令内容，不要额外解释。\n")
        prompt.append("如果需求不明确或无法生成有效指令，请回复\"无法理解该需求，请提供更具体的描述\"。")
        
        return prompt.toString()
    }
    
    /**
     * 调用OpenAI API
     */
    def callOpenAI(String prompt) {
        if (!enabled || !apiKey) {
            throw new Exception("AI功能未启用或API密钥未配置")
        }
        
        try {
            // 构建请求体
            def requestBody = [
                model: model,
                messages: [
                    [
                        role: "user",
                        content: prompt
                    ]
                ],
                max_tokens: maxTokens,
                temperature: temperature
            ]
            
            // 设置请求头
            Map headers = [
                'Content-Type': 'application/json',
                'Authorization': "Bearer ${apiKey}"
            ]
            
            // 创建HttpClient并发送请求
            HttpClient client = new HttpClient(script, apiUrl, headers)
            logger.debug("调用OpenAI API: ${apiUrl}/chat/completions")
            
            def response = client.post("/chat/completions", requestBody)
            
            if (response && response.choices && response.choices.size() > 0) {
                String content = response.choices[0].message.content
                logger.debug("OpenAI API响应成功")
                return content
            } else {
                logger.error("OpenAI API返回格式异常: ${response}")
                throw new Exception("OpenAI API返回格式异常")
            }
            
        } catch (Exception e) {
            logger.error("调用OpenAI API时发生错误: ${e.message}")
            throw e
        }
    }
    
    /**
     * 验证生成的指令格式
     */
    private boolean validateCommand(String command) {
        if (!command) return false
        
        String trimmed = command.trim().toLowerCase()
        
        // 检查是否以run开头
        if (!trimmed.startsWith('run ') && trimmed != 'run') {
            return false
        }
        
        // 基本格式验证通过
        return true
    }
    
    /**
     * 获取AI模块状态信息
     */
    def getStatus() {
        return [
            enabled: enabled,
            model: model,
            apiUrl: apiUrl,
            maxTokens: maxTokens,
            temperature: temperature,
            timeout: timeout
        ]
    }
}